package com.jacky.me.plugin.ui.hook.step2;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.RequiresApi;
import android.view.View;
import android.widget.TextView;

import com.jacky.me.plugin.R;
import com.jacky.me.plugin.framework.BaseActivity;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import dalvik.system.DexClassLoader;

/**
 * Created by jacky on 2017/4/6.
 * banker devel0per
 * <p></p>
 * dx --dex --output=new_log.jar log.jar
 * adb  push  new_log.jar  sdcard/
 */
public class LoarApkActivity extends BaseActivity {

    private boolean mChange;
    private TextView mSkinTv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_load_apk);
        mSkinTv = (TextView) findViewById(R.id.textview);
    }

    /**
     * 获取未安装apk的信息
     *
     * @param context
     * @param pApkFilePath apk文件的path
     * @return
     */
    private String getUninstallApkPkgName(Context context, String pApkFilePath) {
        PackageManager pm = context.getPackageManager();
        PackageInfo pkgInfo = pm.getPackageArchiveInfo(pApkFilePath, PackageManager.GET_ACTIVITIES);
        if (pkgInfo != null) {
            ApplicationInfo appInfo = pkgInfo.applicationInfo;
            return appInfo.packageName;
        }
        return "";
    }

    /**
     * 获取AssetManager   用来加载插件资源
     *
     * @param pFilePath 插件的路径
     * @return
     */
    private AssetManager createAssetManager(String pFilePath) {
        try {
            final AssetManager assetManager = AssetManager.class.newInstance();
            final Class<?> assetManagerClazz = Class.forName("android.content.res.AssetManager");
            final Method addAssetPathMethod = assetManagerClazz.getDeclaredMethod("addAssetPath", String.class);
            addAssetPathMethod.setAccessible(true);
            addAssetPathMethod.invoke(assetManager, pFilePath);
            return assetManager;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    //这个Resources就可以加载非宿主apk中的资源
    private Resources createResources(String pFilePath) {
        final AssetManager assetManager = createAssetManager(pFilePath);
        Resources superRes = this.getResources();
        return new Resources(assetManager, superRes.getDisplayMetrics(), superRes.getConfiguration());
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    private void dynamicLoadApk(String pApkFilePath, String pApkPacketName) {
        File file = getDir("dex", Context.MODE_PRIVATE);
        //第一个参数：是dex压缩文件的路径
        //第二个参数：是dex解压缩后存放的目录
        //第三个参数：是C/C++依赖的本地库文件目录,可以为null
        //第四个参数：是上一级的类加载器
        DexClassLoader classLoader = new DexClassLoader(pApkFilePath, file.getAbsolutePath(), null, getClassLoader());
        try {
            final Class<?> loadClazz = classLoader.loadClass(pApkPacketName + ".R$mipmap");
            //插件中皮肤的名称是skin_one
            final Field skinOneField = loadClazz.getDeclaredField("skin_one");
            skinOneField.setAccessible(true);
            //反射获取skin_one的resousreId
            final int resousreId = (int) skinOneField.get(R.id.class);
            //可以加载插件资源的Resources
            final Resources resources = createResources(pApkFilePath);
            if (resources != null) {
                final Drawable drawable = resources.getDrawable(resousreId);
                mSkinTv.setBackground(drawable);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public void loadApk(View view) {
        String skinType = "";
        if (!mChange) {
            skinType = "taohua.apk";
            mChange = true;
        } else {
            skinType = "meihua.apk";
            mChange = false;
        }
        final String path = Environment.getExternalStorageDirectory() + File.separator + skinType;
        final String pkgName = getUninstallApkPkgName(this, path);
        dynamicLoadApk(path, pkgName);
    }
}
